package cz.tsystems.communications;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.MultipartDataSource;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import javax.security.auth.Subject;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import cz.tsystems.data.DataProvider;
import cz.tsystems.data.SQLiteDBProvider;
import cz.tsystems.portablecheckin.R;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts.Data;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

public class CommunicationService extends IntentService {
	private NotificationManager mNM;
	// private static final int MY_NOTIFICATION_ID=1;
	private int incr = 50;
	private JsonNode rootNode;
	private SQLiteDBProvider dbProvider;
	Notification myNotification;
	final ObjectMapper mapper = new ObjectMapper();

	// Unique Identification Number for the Notification.
	// We use it on Notification start, and to cancel it.
	private int MY_NOTIFICATION_ID = R.string.serviceNotifier;

	 private String URL = "http://dms.t-systems.cz:8090/";//
	// /pchi/ConnectionTest";
//	private String URL = "http://192.168.100.10:8091/";

	public CommunicationService() {
		super("CommunicationService");
	}

	@Override
	public void onCreate() {
		mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		super.onCreate();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	protected void onHandleIntent(Intent intent) {
		Log.d("SERVICE", intent.getStringExtra("ACTION"));
		if (intent.getStringExtra("ACTION").equalsIgnoreCase("GetSilhouette"))
			sendGetMime(intent.getExtras());
		else
			sendGetJson(intent.getExtras());
	}

	@Override
	public void onDestroy() {
		// Cancel the persistent notification.
		mNM.cancel(MY_NOTIFICATION_ID);
		super.onDestroy();
	}

	/**
	 * Show a notification while this service is running.
	 */
	private void showNotification(Bundle data) {
		Context context = getApplicationContext();

		Intent intent = new Intent(context, NotificationReceiverActivity.class);
		intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
		PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent, 0);

		// generate notification
		myNotification = new NotificationCompat.Builder(getApplicationContext()).setContentTitle("Progress").setContentText(data.getString("ACTION")).setContentInfo("content info")
				.setTicker("Notification!").setWhen(System.currentTimeMillis()).setDefaults(Notification.DEFAULT_SOUND)
				// .setAutoCancel(true)
				.setSmallIcon(android.R.drawable.ic_notification_overlay).setProgress(100, incr, false)
				// .addAction(android.R.drawable.btn_minus, "-", pIntent)
				.setContentIntent(pIntent).build();

		mNM.notify(MY_NOTIFICATION_ID, myNotification);
	}

	public void sendGetMime(Bundle data) {

		HttpClient client = new DefaultHttpClient();
		HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000);
		HttpResponse response;
		try {
			String theUrl = URL + data.getString("ACTIONURL");
			HttpGet get = new HttpGet(theUrl);

			Log.d("Message type", data.getString("ACTION"));

			get.addHeader(HTTP.CONTENT_TYPE, "application/json");
			get.addHeader("PCHI-DEVICE-NAME", DataProvider.getSharedDataProvider().getLocalHostName());
			Log.d("DEVICEID", DataProvider.getSharedDataProvider().getDeviceID());
			get.addHeader("PCHI-DEVICE-ID", DataProvider.getSharedDataProvider().getDeviceID());
			get.addHeader("Authorization", "basic " + DataProvider.getSharedDataProvider().getLogin());
			get.addHeader("accept-language", "cz");
			showNotification(data);
			response = client.execute(get);

			if (response != null) {

				if (response.getStatusLine().getStatusCode() != 200) {
					decodeError(response);
					return;
				}

				InputStream in = response.getEntity().getContent();
				ByteArrayOutputStream silImg = new ByteArrayOutputStream();
				FileOutputStream multipartFile = new FileOutputStream("/sdcard/multipartData");
				FileOutputStream imageFile = new FileOutputStream("/sdcard/image.png");
				BufferedReader r = new BufferedReader(new InputStreamReader(in, "UTF-8"));
				StringBuilder total = new StringBuilder();
				String line, boudary = "";
				int len = 0, readetLen;
				boolean readBytes = false;
				byte buffer[] = new byte[1024];
				Map<String, Object> silhouette = new HashMap<String, Object>();
				List<Map<String, Object>> silhouettes = new ArrayList<Map<String, Object>>();
				byte[] mpd = new byte[(int) response.getEntity().getContentLength()];

				// len = in.read(mpd);
				// multipartFile.write(mpd);
				// multipartFile.close();
				// in.reset();

				while ((line = r.readLine()) != null) {

					if (boudary.isEmpty() && line.length() > 0) {
						boudary = line;
						continue;
					}

					if (line.indexOf(boudary) != -1) {
						readBytes = false;
						silhouette.put("IMAGE", silImg.toByteArray());
						imageFile.write(silImg.toByteArray());
						imageFile.close();
						silImg.flush();
						silImg.reset();
						silhouettes.add(silhouette);
					}

					if (readBytes) {
						// int offset = 0, size = 1024;
						// while((len = in.read(buffer, offset, size)) != -1)
						// {
						// silImg.write(buffer);
						// byte b[] = "\n".getBytes("Latin-1");
						// int index = Arrays.binarySearch(buffer, b[0]);
						// line = new String(buffer, "UTF-8")
						// }
						silImg.write(line.getBytes("Latin-1"));

						continue;
					}

					if (line.length() > 0) {
						String lineUTF8 = new String(line.getBytes("UTF-8"), "UTF-8");
						String[] silData = lineUTF8.split(":");
						silhouette.put(silData[0].trim(), silData[1].trim());
					} else
						readBytes = true;

					Log.d("getingData", line);
				}

				// String path =
				// Environment.getExternalStorageDirectory().getAbsolutePath();
				// File file = new File(path, "/log.txt");
				// FileOutputStream output = new FileOutputStream(file);
				// int bufferSize = 1024;
				/*
				 * InputStreamReader iStreamReader = new
				 * InputStreamReader(response.getEntity().getContent()); long
				 * contentLength = response.getEntity().getContentLength();
				 * char[] buffer = new char[(int)contentLength]; int len = 0;
				 * len = iStreamReader.read(buffer); if(len < contentLength)
				 * Log.e("RESPONSE ERROR", "lengt is: " + len + ", should be: "
				 * + contentLength); else parseMIMEContent(buffer);
				 */

				// File file2 = new File(path, "/log2.txt");
				// DataOutputStream out =
				// new DataOutputStream(openFileOutput(file2.getAbsolutePath(),
				// Context.MODE_PRIVATE));
				// out.writeBytes(total.toString());
				// out.close();

				// Get the data in the entity
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	// private byte[] readLine(byte[] data)
	// {
	// byte[] line;
	//
	// while()
	//
	// return line;
	// }

	// private void parseMIMEContent(char[] buffer) {
	//
	// BufferedReader r = new BufferedReader(buffer);
	// StringBuilder total = new StringBuilder();
	// String line;
	// while ((line = r.readLine()) != null) {
	// total.append(line);
	// }
	//
	// }

	public void sendGetJson(Bundle data) {
		HttpClient client = new DefaultHttpClient();
		HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000);
		HttpResponse response;
		try {
			String theUrl = URL + data.getString("ACTIONURL");
			HttpGet get = new HttpGet(theUrl);

			Log.d("Message type", data.getString("ACTION"));

			get.addHeader(HTTP.CONTENT_TYPE, "application/json");
			get.addHeader("PCHI-DEVICE-NAME", DataProvider.getSharedDataProvider().getLocalHostName());
			Log.d("DEVICEID", DataProvider.getSharedDataProvider().getDeviceID());
			get.addHeader("PCHI-DEVICE-ID", DataProvider.getSharedDataProvider().getDeviceID());
			get.addHeader("Authorization", "basic " + DataProvider.getSharedDataProvider().getLogin());
			get.addHeader("accept-language", "cz");
			showNotification(data);
			response = client.execute(get);

			/* Checking response */
			if (response != null) {

				if (response.getStatusLine().getStatusCode() != 200) {
					decodeError(response);
					return;
				}

				InputStream in = response.getEntity().getContent();
				BufferedReader r = new BufferedReader(new InputStreamReader(in, "UTF-8"));
				StringBuilder total = new StringBuilder();
				String line;
				while ((line = r.readLine()) != null) {
					total.append(line);
					Log.d("getingData", line);
				}

				/*
				 * String path =
				 * Environment.getExternalStorageDirectory().getAbsolutePath();
				 * File file = new File(path, "/log.txt"); FileOutputStream
				 * output = new FileOutputStream(file); int bufferSize = 1024;
				 * byte[] buffer = new byte[bufferSize]; int len = 0; int i=0;
				 * while ((len = in.read(buffer)) != -1) { i++; // if(len <
				 * bufferSize) // buffer[len] = '\n'; output.write(buffer, 0,
				 * len); String tmp = new String(buffer, "UTF-8");
				 * Log.d("response "+i, tmp); total.append(tmp); }
				 */
				// File file2 = new File(path, "/log2.txt");
				// DataOutputStream out =
				// new DataOutputStream(openFileOutput(file2.getAbsolutePath(),
				// Context.MODE_PRIVATE));
				// out.writeBytes(total.toString());
				// out.close();

				Log.d("response", total.toString());
				try {
					decodeMessage(data, total.toString());
				} catch (JsonProcessingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				// Get the data in the entity
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void decodeError(HttpResponse response) {

	}

	private void decodeMessage(Bundle data, String response) throws JsonProcessingException, IOException {
		Intent i = new Intent("recivedData");
		if (data.getString("ACTION").equalsIgnoreCase("Login"))
			decodeLogin(response);
		else if (data.getString("ACTION").equalsIgnoreCase("GetStaticData"))
			decodeStaticData(response);
		else if (data.getString("ACTION").equalsIgnoreCase("GetSilhouette"))
			decodeSilhouette(response);
		else if (data.getString("ACTION").equalsIgnoreCase("GetBanners"))
			decodeBanners(response);
		else if (data.getString("ACTION").equalsIgnoreCase("CheckinOrderList"))
			DataProvider.getSharedDataProvider().setPlanZakazk(mapper.readTree(response));
		i.putExtra("requestData", data);
		LocalBroadcastManager.getInstance(this).sendBroadcast(i);
	}


	private void decodeBanners(String response) {
		// TODO Auto-generated method stub

	}

	private void decodeSilhouette(String response) {
		// TODO Auto-generated method stub

	}

	private void decodeStaticData(String response) throws JsonProcessingException, IOException {
		// TODO Auto-generated method stub

		dbProvider = DataProvider.getSharedDataProvider().getTheDBProvider();

		rootNode = mapper.readTree(response);

		doInserTable("BRAND");
		doInserTable("BRAND_CARBODYCODE");
		doInserTable("BRAND_CARBODYTYPE");
		doInserTable("BRAND_LOC");
		doInserTable("BRAND_SILHOUETTE");
		doInserTable("CAR_EQUIPMENT");
		doInserTable("CAR_EQUIPMENT_LOC");
		doInserTable("CARBODYTYPE");
		doInserTable("CUSTOMER_CATEGORY");
		doInserTable("CUSTOMER_CATEGORY_LOC");
		doInserTable("FUEL");
		doInserTable("FUEL_LOC");
		doInserTable("HISTORY_TYPE");
		doInserTable("HISTORY_TYPE_LOC");
		doInserTable("CHCK_PART");
		doInserTable("CHCK_PART_LOC");
		doInserTable("CHCK_PART_POSITION");
		doInserTable("CHCK_PART_POSITION_STATUS");
		doInserTable("CHCK_POSITION");
		doInserTable("CHCK_POSITION_LOC");
		doInserTable("CHCK_REQUIRED");
		doInserTable("CHCK_REQUIRED_LOC");
		doInserTable("CHCK_STATUS");
		doInserTable("CHCK_STATUS_LOC");
		doInserTable("CHCK_UNIT");
		doInserTable("CHCK_UNIT_LOC");
		doInserTable("CHECK_OFFER");
		doInserTable("CHECK_OFFER_LOC");
		doInserTable("CHECK_SCENARIO");
		doInserTable("CHECK_SCENARIO_LOC");
		doInserTable("CHECK_SCENARIO_UNIT");
		doInserTable("CHECK_SERVICE");
		doInserTable("CHECK_SERVICE_LOC");
		doInserTable("OBD_DTC");
		doInserTable("OBD_DTC_LOC");
		doInserTable("OBD_FUEL");
		doInserTable("OBD_FUEL_LOC");
		doInserTable("SILHOUETTE");
		doInserTable("SILHOUETTE_IMAGE");
		doInserTable("SILHOUETTE_TYPE");
		doInserTable("SPARE_PART_DISPON");
		doInserTable("SPARE_PART_DISPON_LOC");
		doInserTable("SYS_CONFIG");
		doInserTable("TYPE_CODE");
		doInserTable("WORKSHOP_PACKET_BRIDGE");
	}

	private void doInserTable(String tableName) {
//		JsonNode dataNode = rootNode.path(tableName);
//		Iterator<JsonNode> ite = dataNode.elements();
		dbProvider.insertTableData(tableName, rootNode.path(tableName).elements());
	}

	private void decodeLogin(String data) {
		try {

			dbProvider = DataProvider.getSharedDataProvider().getTheDBProvider();
			rootNode = mapper.readTree(data);
			JsonNode userNode = rootNode.path("USER");
			JsonNode configNode = rootNode.path("CONFIGURATION");

			// JSONObject jObj = new JSONObject(data);
			DataProvider.getSharedDataProvider().setLogetUser(userNode);
			DataProvider.getSharedDataProvider().setConfiguration(configNode);
			Log.d("JSONUSER", userNode.get("PERSONAL_ID").textValue());// getJSONObject("USER").getString("PERSONAL_ID"));
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
